home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / nihcl-30.lha / nihcl-3.0 / errfac / errors.c < prev    next >
C/C++ Source or Header  |  1990-05-15  |  6KB  |  247 lines

  1. /* errors.c -- Error reporting library routines
  2.  
  3.     THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
  4.     "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
  5.     AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
  6.     CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
  7.     PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
  8.     RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
  9.  
  10. Author:
  11.     S.M. Orlow
  12.     Systex,Inc.
  13.     Beltsville, MD 20705
  14.     301-474-0111
  15.     June, 1986
  16.  
  17. Contractor:
  18.     K. E. Gorlen
  19.     Bg. 12A, Rm. 2017
  20.     Computer Systems Laboratory
  21.     Division of Computer Research and Technology
  22.     National Institutes of Health
  23.     Bethesda, Maryland 20892
  24.     Phone: (301) 496-5363
  25.     uucp: uunet!nih-csl!kgorlen
  26.     Internet: kgorlen@alw.nih.gov
  27.  
  28. Function:
  29.  
  30. $Log:    errors.c,v $
  31.  * Revision 3.0  90/05/15  22:37:00  kgorlen
  32.  * Release for 1st edition.
  33.  * 
  34. */
  35.  
  36. static const char rcsid[] = "$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/errfac/RCS/errors.c,v 3.0 90/05/15 22:37:00 kgorlen Rel $";
  37.  
  38. #include "errors.h"
  39. #include "errlib.h"
  40. #include <libc.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <stdarg.h>
  44.  
  45. ErrFac errfac[MAX_FACILITIES];    // error reporting facilities
  46. static FILE* fout = stderr;        // current error FILE
  47. static int print_severity = WARNING;    // print threshhold
  48. static int exit_severity  = ERROR;    // exit threshhold
  49. #define format_severity 1
  50. #define format_facility 2
  51. static char* sevmsg[5] = { "success","info","warning","error","fatal" };
  52. static int format_cntl    = 3;    // format control: 0=~facility&~severity,
  53.                 // 1=~facility, 2=~severity, 3=all
  54. static int dump_cntl = 0;    // dump control: not implemented
  55.  
  56. static char* bad_fac_msg = "*** Invalid Facility (%d) -- from error (%d)\n";
  57. static char* bad_err_msg="*** Error No.(%d) out of range -- from error (%d)\n";
  58.  
  59. void seterropt(int esev, int psev, int dump, int fmt, FILE* filep) 
  60. {
  61.     exit_severity = esev;
  62.     print_severity = psev;
  63.     dump_cntl = dump;
  64.     format_cntl = fmt;
  65.     if ( filep == 0 )
  66.       fout = stderr;
  67.          else // use stdout
  68.           fout = filep;
  69. }
  70.  
  71. void geterropt(int& esev,int& psev,int& dump,int& fmt,FILE*& filep) 
  72. {
  73.     esev = exit_severity;
  74.     psev = print_severity;
  75.     fmt = format_cntl;
  76.     dump = dump_cntl;
  77.     filep = fout;
  78.     }
  79.  
  80. static void printerror(int sev,const char* prefix,char* msg) 
  81. {
  82.     char facnameprefix[80];
  83.     char severityprefix[80];
  84.     if ( format_cntl&format_facility ) 
  85.       sprintf(facnameprefix,"%s: ",errfac[FACILITY_CODE(errno)].longname);
  86.          else // no facility prefix
  87.       facnameprefix[0] = '\0';
  88.         if ( format_cntl&format_severity )
  89.       sprintf(severityprefix,"%s: ",sevmsg[-sev]);
  90.      else // no severity prefix
  91.           severityprefix[0] = '\0';
  92.     fprintf(fout,"%s%s%s%s\n",prefix,facnameprefix,severityprefix,msg);
  93. }
  94.  
  95. void errfac_prepNextArg(char* p,char* q) 
  96. {
  97.     int flag = 1;
  98.     while ( *p != '\0' ) {
  99.       if ( flag&&(*p == '\001') ) {
  100.         *(q++) = '%';
  101.         ++p;
  102.         flag = 0;
  103.         }
  104.            else // transfer character
  105.             *(q++) = *(p++);
  106.           }
  107.         *q = '\0';
  108. }
  109.  
  110. void errfac_prepText(char* p, char* q)
  111. {
  112.      while ( *p != '\0' ) {
  113.     if ( *p == '%' ) {
  114.       if ( *(p+1) == '%' ) {// skip "%%"
  115.             *q++ = *p++;
  116.         *q++ = *p++;
  117.         }
  118.         else {// change '%' to '^A'
  119.         *q++ = '\001';    
  120.         ++p;
  121.             }
  122.       }
  123.      else // transfer character
  124.       *q++ = *p++;
  125.     }
  126.      *q = '\0';
  127. }
  128.  
  129. void errfac_errorMessage(int sev,char* msg)
  130. {
  131.     if ( errfac_isPrintSeverity(sev) )  // print error msg
  132.       printerror(sev,"",msg);
  133.  
  134.     if ( errfac_isExitSeverity(sev) ) {
  135.         if ( dump_cntl ) abort();
  136.           else exit(1);
  137.         }
  138. }
  139.  
  140. ErrFac* errfac_at(int err)
  141. {
  142.     char buf[128];
  143.     /* facility code */
  144.     int fac_code = FACILITY_CODE(err);
  145.  
  146.     if ( (fac_code < 0)||(fac_code > MAX_FACILITIES) ) { // bad facility
  147.        sprintf(buf,bad_fac_msg,fac_code,err);
  148.        errfac_errorMessage(ERROR,buf);
  149.        }
  150.     // valid facility
  151.         ErrFac fac = errfac[fac_code];
  152.  
  153. #ifdef TRACE
  154. printf("seterror> Facility Code: %d  Facility Name: %s  Last Error: %d\n",
  155.     fac_code,fac.longname,fac.last);
  156. #endif
  157.        /* error number */
  158.        int err_code = OFFSET_INDEX(err);
  159.        int first_code = err&FAC_MASK;
  160.  
  161.        if ( (err < first_code)||(err > fac.last) ) { // bad error
  162.          sprintf(buf,bad_err_msg,err_code,err);
  163.          errfac_errorMessage(ERROR,buf);
  164.          }
  165.     return &errfac[fac_code];
  166. }
  167.  
  168. char* errfac_argumentCodes(int err)
  169. {
  170.     ErrFac* fac = errfac_at(err);
  171.     int err_code = OFFSET_INDEX(err);
  172.     return fac->errlist[err_code].args;
  173. }
  174.  
  175. char* errfac_errorText(int err,char* buf)
  176. {
  177.     ErrFac* fac = errfac_at(err);
  178.     int err_code = OFFSET_INDEX(err);
  179.     char* txt = fac->errlist[err_code].text;
  180.     if ( buf )
  181.        errfac_prepText(txt/*IN*/,buf/*OUT*/);
  182.     return txt;
  183. }
  184.  
  185. int errfac_severity(int err)
  186. {
  187.     ErrFac* fac = errfac_at(err);
  188.     int err_code = OFFSET_INDEX(err);
  189.     return fac->errlist[err_code].severity;
  190. }
  191.  
  192. int errfac_printSeverity() { return print_severity; }
  193. int errfac_exitSeverity() { return exit_severity; }
  194. int errfac_isPrintSeverity(int s) { return (s<=print_severity); }
  195. int errfac_isExitSeverity(int s) { return (s<=exit_severity); }
  196.  
  197. #ifdef sparc
  198. // Use magic name to make stdarg work
  199. #define sev __builtin_va_alist
  200. #endif
  201.  
  202. int seterror(int err, int sev, ...)
  203. {
  204. #ifdef TRACE
  205. printf("seterror> Error No: %d  Severity: %d\n",err,sev);
  206. #endif
  207.     errno = err;
  208.         char buf[132],buf0[132];
  209.  
  210.     errfac_errorText(err,buf/*OUT*/);
  211.      
  212.     char* p = errfac_argumentCodes(err);
  213. #ifdef TRACE
  214. printf("seterror> argument codes %s\n",p);
  215. #endif
  216.     va_list ap;
  217.     va_start(ap,sev);
  218.     while ( *p != '\0' ) { // set up next arg
  219.       errfac_prepNextArg(buf/*IN*/,buf0/*OUT*/);
  220.       switch ( *(p++) ) {
  221.          case 'I': 
  222.         int i = va_arg(ap,int);
  223.              sprintf(buf,buf0,i);
  224.                   break;
  225.          case 'S':
  226.         char* s = va_arg(ap,char*);
  227.              sprintf(buf,buf0,s);
  228.             break;
  229.          case 'D':
  230.             double d = va_arg(ap,double);
  231.              sprintf(buf,buf0,d);
  232.             break;
  233.          default : // ignored
  234.             break;
  235.          }// end switch
  236.           }// end while
  237.     va_end(ap);
  238.  
  239.     int severity = (sev < 0)? sev:(errfac_severity(err));
  240.     errfac_errorMessage(severity,buf);
  241.     if ( errfac_isExitSeverity(severity) ) {
  242.        printf("NIHCL: fatal: Tried to continue after error %d\n",err);
  243.        abort();
  244.        }
  245.     return severity;
  246. }
  247.